﻿// LoadStoreMultipleInstruction.cs
// Load Store Multiple instruction class. One of the parent classes.


using System;


namespace armsim
{

    public class LoadStoreMultipleInstruction : BaseInstruction
    {
        /// <summary>
        /// Pre/Post Index flag
        /// </summary>
        public uint P { get; protected set; }

        /// <summary>
        /// Offset sign
        /// </summary>
        public uint U { get; protected set; }

        /// <summary>
        /// Byte/Word access
        /// </summary>
        public uint B { get; protected set; }

        /// <summary>
        /// Writeback
        /// </summary>
        public uint W { get; protected set; }

        /// <summary>
        /// Load or Store?
        /// </summary>
        public uint L { get; protected set; }

        /// <summary>
        /// The first Operand register
        /// </summary>
        public uint Rn { get; protected set; }

        /// <summary>
        /// The Register List
        /// </summary>
        public LSMRegisterList RegisterList { get; protected set; }

        /// <summary>
        /// Initializes a new LoadStoreMultipleInstruction with the P, U, B, W, L, Rn, and RegistList fields set
        /// </summary>
        /// <param name="instruction">Encoded 32bit instruction to decode</param>
        public LoadStoreMultipleInstruction(uint instruction) : base(instruction)
        {
            this.P = VirtualMemory.ExtractBits(instruction, 24, 24);
            this.U = VirtualMemory.ExtractBits(instruction, 23, 23);
            this.B = VirtualMemory.ExtractBits(instruction, 22, 22);
            this.W = VirtualMemory.ExtractBits(instruction, 21, 21);
            this.L = VirtualMemory.ExtractBits(instruction, 20, 20);
            this.Rn = VirtualMemory.ExtractBits(instruction, 16, 19);
            this.RegisterList = new LSMRegisterList(instruction);

        }
        
        /// <summary>
        /// Creates an assembly string for the instruction
        /// </summary>
        /// <param name="cpu">central processing unit</param>
        /// <returns>the assembly string</returns>
        public override string ToAssembly(VirtualCPU cpu)
        {
            return String.Format(this.W == 1u ? "{0}!, {1}" : "{0}, {1}", VirtualMemory.RegToAssembly(this.Rn), RegisterList.ToAssembly(cpu));
        }
    }
}
